#include "pantalla.h"

// Variables globales
SDL_Surface *grid,*fondo,*j_rojo,*j_azul,*pierde,*gana,*font;
Uint8 *keys;
int done = 0;
extern t_scr principal;
SDL_Surface *screen;							// Pantalla SDL
SDL_Thread *actualizar;
extern char nombre1[20];
extern char nombre2[20];

// Semáforo del thread pantalla
extern sem_t mutex_pantalla;

// Semáforo del thread periferico
extern sem_t mutex_periferico;

// Semáforos movimientos
extern sem_t nuevo_mov;
extern sem_t sem_mov;
extern sem_t mov_valido;

// Thread
void* thread_pantalla(void* arg)
{
	SDL_Rect dest;
	int ret=-1;
	s_mov* mov = (s_mov*) arg;
	
	// Funcion inicializacion
	cargar();
		
	// Colores
	SDL_Color rojo  = {255,0,0};
	SDL_Color verde = {0,255,0};
	SDL_Color azul  = {0,0,255};
	
	// Funcion presentacion
	presentacion();
	
	// Dibujo base gráfica del cliente
	dibujar_base();
    
    actualizar = SDL_CreateThread(actualizar_pantalla, NULL);
		
	while(1)
	{
		// Espero sincronización
		lock_pantalla();
		
		if(mov->estado != GANADOR && mov->estado != PERDEDOR)
			dibujar_grilla();
		
		else
		{
			if(mov->estado == GANADOR)
				ganador_partida();											// Cliente ganó la partida
			else
				perdedor_partida();											// Cliente perdió la partida
				
			dibujar_grilla();
		}
				
		// Mutex estructura movimiento
		sem_post(&sem_mov);
		
		// Actualizo pantalla
		SDL_Flip(screen);
	}
}

// Funciones secundarias
void start_sdl()
{
	// Iniciar SDL
	if(SDL_Init(SDL_INIT_VIDEO) < 0)
		error(SDL_GetError());

	atexit(SDL_Quit);
	
	// Modo de video
	screen = SDL_SetVideoMode(WIDTH, HEIGHT, BPP, SDL_HWSURFACE);
	if(screen == NULL)
		error(SDL_GetError());
}

void cargar()
{
	// Carga imagenes
	fondo = IMG_Load("recursos/img/fondo2.jpg");
	if(fondo == NULL)
		error(SDL_GetError());
	
	grid = IMG_Load("recursos/img/grilla.png");
	if(grid == NULL)
		error(SDL_GetError());
	
	j_rojo = IMG_Load("recursos/img/tux2.png");
	if(j_rojo == NULL)
		error(SDL_GetError());
	
	j_azul = IMG_Load("recursos/img/wlogo.png");
	if(j_azul == NULL)
		error(SDL_GetError());
		
	pierde = IMG_Load("recursos/img/loser.png");
	if(pierde == NULL)
		error(SDL_GetError());
		
	gana = IMG_Load("recursos/img/winner.png");
	if(gana == NULL)
		error(SDL_GetError());
	
	font = IMG_Load("recursos/fonts/font.png");
	if(font == NULL)
		error(SDL_GetError());
}

void presentacion()
{
	SDL_Rect data;
	SDL_Color verde = {0,255,0};
	
	//sleep(2);
	limpiar_screen();
}

void limpiar_screen()
{
	// Pinto la pantalla de negro
	SDL_FillRect(screen, NULL, 0);
}

void dibujar_grilla()
{
	SDL_Rect dest;
	int i,j;
	
	// Desplazamiento (x,y,ancho_imagen,altura_imagen)
	dest.x = GRID_POSX;
	dest.y = GRID_POSY;
	dest.w = grid -> w;
	dest.h = grid -> h;
	
	// Mando grilla a pantalla
	SDL_BlitSurface(grid, NULL, screen, &dest);
	
	// Dibujar elementos en la matriz
	dest.w = ANCHO_ITEM;
	dest.h = ANCHO_ITEM;
	
	for(i=0;i<3;i++)
		for(j=0;j<3;j++)
			if(principal.matriz[i][j])
			{
				// Posición de objeto
				dest.x = 10 + GRID_POSX + j*(grid->w/3);
				dest.y = 10 + GRID_POSY + i*(grid->w/3);
				
				switch(principal.matriz[i][j])
				{
					case ESFERA:
						SDL_BlitSurface(j_rojo, NULL, screen, &dest);
					break;
					case CUBO:
						SDL_BlitSurface(j_azul, NULL, screen, &dest);
					break;
				}
			}
	
	// Actualizar pantalla
	SDL_Flip(screen);
}

void dibujar_base()
{
	SDL_Rect dest;
	
	// Desplazamiento (x,y,ancho_imagen,altura_imagen)
	dest.x = dest.y = 0;
	dest.w = fondo -> w;
	dest.h = fondo -> h;
	
	// Mandar fondo a pantalla
	SDL_BlitSurface(fondo, NULL, screen, &dest);
	
	dibujar_grilla();
	
	// Actualizar pantalla
	SDL_Flip(screen);
}

void escritura(char* cad)
{
	int ancho=95,alto=160;
	
}

void ganador_partida()
{
	SDL_Rect dest;
	
	// Desplazamiento (x,y,ancho_imagen,altura_imagen)
	dest.x = dest.y = 0;
	dest.w = gana -> w;
	dest.h = gana -> h;
	
	// Actualizar pantalla con ganador
	SDL_BlitSurface(gana, NULL, screen, &dest);
	SDL_Flip(screen);
	SDL_Delay(1000);
	limpiar_screen();
	dibujar_base();
}

void perdedor_partida()
{
	SDL_Rect dest;
	
	// Desplazamiento (x,y,ancho_imagen,altura_imagen)
	dest.x = dest.y = 0;
	dest.w = pierde -> w;
	dest.h = pierde -> h;
	
	// Actualizar pantalla con perdedor
	SDL_BlitSurface(pierde, NULL, screen, &dest);
	SDL_Flip(screen);
	SDL_Delay(1000);
	limpiar_screen();
	dibujar_base();
}

int valida_posicion(SDL_Event event)
{
	if(event.button.x > GRID_POSX && event.button.x < GRID_POSX + grid -> w)//(GRID_POSX + ANCHO_ITEM))
		if(event.button.y > GRID_POSY && event.button.y < GRID_POSY + grid -> h)//(GRID_POSY + ANCHO_ITEM))
			return 1;
	return 0;
}

int obtener_posicion(SDL_Event event)
{
	int valx = (event.button.x - GRID_POSX);
	int valy = (event.button.y - GRID_POSY);
	
	valx /= grid->w/3;
	valy /= grid->w/3;
	
	switch(valy)
	{
		case 0:
			if(valx == 0) return 0;
			if(valx == 1) return 1;
			else          return 2;
			break;
			
		case 1:
			if(valx == 0) return 3;
			if(valx == 1) return 4;
			else          return 5;
			break;
			
		case 2:
			if(valx == 0) return 6;
			if(valx == 1) return 7;
			else          return 8;
			break;
	}
}

void* thread_lectura(void* arg)
{
	SDL_Event event;
	int ret = -1, done = 0;
	s_mov* mov = (s_mov*) arg;
	
	// Ignorar movimiento mouse y mouse
	SDL_EventState(SDL_MOUSEMOTION, SDL_IGNORE);
	SDL_EventState(SDL_MOUSEBUTTONDOWN, SDL_IGNORE);
		
	while(1)
	{
		// Espero sincronismo
		lock_periferico();
		printf("Teclado espera ingreso\n");
		event.button.x = event.button.y = done = 0;
		
		// Activo lectura teclado
		SDL_EventState(SDL_MOUSEBUTTONDOWN, SDL_ENABLE);
		
		// Espero por evento (espera activa = fix)
		while(SDL_WaitEvent(&event) && !done)
			if(event.type == SDL_MOUSEBUTTONDOWN)
			{
				if(valida_posicion(event))
				{
					ret = obtener_posicion(event);
					
					mov->posicion = ret+1;
					
					printf("Boton %d presionado en (%d,%d)\n",event.button.button,event.button.x,event.button.y);
					printf("Pos: %d\n",mov->posicion);
					
					// Termino ingreso de eventos
					done = 1;
					
					// Deshabilito entrada de eventos
					SDL_EventState(SDL_MOUSEBUTTONDOWN, SDL_IGNORE);
				}
					
				printf("Valido? %d\n",valida_posicion(event));
			}
			
		// Aviso mensaje válido a proceso cliente
		sem_post(&nuevo_mov);
	}
}

// Sincronización pantalla
void lock_pantalla()
{
	printf("** Pantalla locked\n");
	sem_wait(&mutex_pantalla);
}

void unlock_pantalla()
{
	printf("** Pantalla unlocked\n");
	sem_post(&mutex_pantalla);
}

// Sincronización periferico
void lock_periferico()
{
	printf("¨¨ Teclado locked\n");
	sem_wait(&mutex_periferico);
}

void unlock_periferico()
{
	printf("¨¨ Teclado unlocked\n");
	sem_post(&mutex_periferico);
}

// Función finalización
void finalizar_sdl()
{
	SDL_FreeSurface(screen);							// Pantalla SDL
	SDL_FreeSurface(grid);
	SDL_FreeSurface(fondo);
	SDL_FreeSurface(j_rojo);
	SDL_FreeSurface(j_azul);
	SDL_FreeSurface(font);
    SDL_KillThread(actualizar);
    SDL_Quit();
}

int actualizar_pantalla(void *data){
	SDL_Event event;

	while(1)
	{
		event.button.x = event.button.y = done = 0;
        SDL_EventState(SDL_VIDEOEXPOSE, SDL_ENABLE);
		
		// Espero por evento (espera activa = fix)
		while(SDL_WaitEvent(&event))
			if(event.type == SDL_VIDEOEXPOSE)
	            // Actualizar pantalla
	            SDL_Flip(screen);
	}
}

